package com.init.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.init.utils.JwtUtils;
import com.init.utils.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * jwt 校验拦截器
 */
public class JwtTokenInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(JwtTokenInterceptor.class);
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }
        String token = request.getHeader("Authorization");
        log.info("@@@token: {}", token);

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            try {
                if (JwtUtils.verify(token)) {
                    String role = JwtUtils.getRole(token);
                    log.info("@@@role: {}", role);
                    // 保存accountId到request中，int类型
                    request.setAttribute("accountId", JwtUtils.getAccountId(token));
                    if (isAuthorized(request.getRequestURI(), role)) {
                        log.info("@@@{} 访问 {} 成功", role, request.getRequestURI());
                        return true;
                    } else {
                        log.info("@@@{} 访问 {} 失败", role, request.getRequestURI());
                        return respondWithError(response, HttpServletResponse.SC_OK, R.tokenError());
                    }
                } else {
                    return respondWithError(response, HttpServletResponse.SC_OK, R.tokenError());
                }
            } catch (Exception e) {
                log.error("Token verification failed", e);
                return respondWithError(response, HttpServletResponse.SC_OK, R.tokenError());
            }
        } else {
            return respondWithError(response, HttpServletResponse.SC_OK, R.tokenError());
        }
    }

    private boolean isAuthorized(String uri, String role) {
        if ("admin".equals(role)) {
            return uri.startsWith("/api/admin") || uri.startsWith("/api/user");

        } else if ("user".equals(role)) {
            return uri.startsWith("/api/user");
        }
        return false;
    }

    private boolean respondWithError(HttpServletResponse response, int status, R errorResponse) throws Exception {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.setStatus(status);
        response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
        return false;
    }
}
